let a = () => {
  function b() {
    console.log(this); // this 指向了 global
  }

  b();
};

a();

// 普通调用的 this

// class 中的 this ， 构造 函数 中 的 this  都属于 new 中的 this 这 种情况

// 箭头函数  3 种情况

// this 的 指向 就是 函数 调用对象 ，没有 就是 global 或者 window ，new 的时候 this 就指向创建的 对象

// 箭头函数的使用会导致 函数执行的时候指向的this是函数定义的 作用域的 this  ，那 这个作用域 执行了  和 未被 执行 的 情况 分别是 怎样的

// es6中的 class 其实就是个构造函数  ，上面的方法是写在原型链上的 ， new 的 时候 , class 中 的 this 的 指向 就是 创建 的 对象 。
// constructor 不是原型链上面的，是写在 构造函数内部的。new 的 时候 通过 this 进行 调用。

function MyClass() {
  this.a = 5;

  this.__constructor = function (a) {
    this.a = a;
  };

  this.__constructor(...arguments);
}

let myclass = new MyClass(10);

console.log(myclass.a);

function MyPromise() {
  this.a = 5;

  MyPromise.prototype.resolve = () => {
    console.log(this.a);
  };
}

let promise = new MyPromise();

promise.resolve();

// 不是箭头函数的话,this 的指向是 在 执行 的 时候确定的

// 箭头函数 是定义的时候 进行绑定的 , 箭头函数在 函数内部定义，那么当函数被执行的时候，箭头函数的 this 指向 就和 函数一样

// 箭头函数 在 class 中 定义 的 ，那么 new 的 时候， this 就指向 创建的 对象

// 在 class 中 定义的 方法 没有 使用 this ，最终 也指向 新创建的 对象 是 因为 隐式原型 调用 的 关系

//  箭头函数 在 obj 中 定义的时候 , this 指向 对象的 外部作用域 的 this

// 箭头函数 在全局 的 环境中 定义，那么 this 指向 就是

// 箭头函数 的 this 和它的外部作用域保持一致。

// this 的 指向 完全取决于 函数 在哪里被调用

// this 在 执行上下文中，指向 当前指向上下文的调用者

// 对象中 写 方法 和 class 中 写方法 都有 3 种 写法

let c = {
  b: 5,
  say: () => {
    console.log(this);
  },
  says() {
    console.log(this);
  },

  saysss: function () {
    console.log(this);
  },
};

console.log(c.say());

function App() {
  let obj = {
    a: 5,
    getInstance: function () {
      return () => {
        console.log(this);
      };
    },
  };

  return obj.getInstance();
}

let app = App();

console.log(app());

// this 的 指向和 它 的 上一个执行上下文 的 this 的 指向 没关系 , 和 栈 和 执行上下文的顺序也没关系

let d = {
  a: 5,
  say() {
    console.log(this.a);

    function e() {
      console.log(this);
    }

    e();
  },
};

d.say();

class VAR {
  a = 5;

  constructor() {
    console.log(10);
  }

  say = function () {
    console.log(this.a);
  };

  says() {}

  saysss = () => {};
}

console.log(new VAR().__proto__);
